package com.love.rongcommon.db.algorithm;

import cn.hutool.core.text.StrFormatter;
import com.google.common.collect.Lists;
import com.google.common.collect.Range;
import lombok.extern.slf4j.Slf4j;
import org.apache.shardingsphere.api.sharding.standard.PreciseShardingAlgorithm;
import org.apache.shardingsphere.api.sharding.standard.PreciseShardingValue;
import org.apache.shardingsphere.api.sharding.standard.RangeShardingAlgorithm;
import org.apache.shardingsphere.api.sharding.standard.RangeShardingValue;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Collection;

/**
 * 按月分表
 * 格式：表名_202001
 * 如：cl_log_202001
 */
@Slf4j
@Component
public class TimeAlgorithmWithMonth implements PreciseShardingAlgorithm<String>, RangeShardingAlgorithm<String> {
    private static DateTimeFormatter fmt = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
    private static DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMM");

    @Override
    public String doSharding(Collection<String> collection, PreciseShardingValue<String> preciseShardingValue) {
        String logicTableName = preciseShardingValue.getLogicTableName();
        String index = LocalDateTime.parse(preciseShardingValue.getValue(), fmt).format(formatter);
        return StrFormatter.format("{}_{}", logicTableName, index);
    }

    /**
     * between and 有效
     * @param collection
     * @param rangeShardingValue
     * @return
     */
    @Override
    public Collection<String> doSharding(Collection<String> collection, RangeShardingValue<String> rangeShardingValue) {
        Collection<String> routeTables = Lists.newArrayList();

        // 获取区间时间
        Range<String> valueRange = rangeShardingValue.getValueRange();
        LocalDateTime beginTime = LocalDateTime.parse(valueRange.lowerEndpoint(), fmt);
        LocalDateTime endTime = LocalDateTime.parse(valueRange.upperEndpoint(), fmt);

        // 获取区间表名
        while (beginTime.isBefore(endTime)) {
            routeTables.add(StrFormatter.format("{}_{}", rangeShardingValue.getLogicTableName(), beginTime.format(formatter)));
            beginTime = beginTime.plusMonths(1);
        }

        // 检查最后一个
        String last = StrFormatter.format("{}_{}", rangeShardingValue.getLogicTableName(), endTime.format(formatter));
        if (!routeTables.contains(last)) {
            routeTables.add(last);
        }

        return routeTables;
    }
}
